package com.supermap.ipfs;

import com.alibaba.fastjson.JSONObject;
import io.ipfs.api.IPFS;
import io.ipfs.api.MerkleNode;
import io.ipfs.api.NamedStreamable;
import io.ipfs.multihash.Multihash;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

/**
 * @author liqs
 * @version 1.0
 * @date 2020/5/6 12:06
 */
public class IpfsClient {


    private Logger logger = Logger.getLogger(IpfsClient.class.toString());
    private  IPFS ipfs;

    public IpfsClient(String ip, String port){
        try {
            InetAddress addr= InetAddress.getByName(ip);
            String str = addr.getHostAddress();
            ipfs = new IPFS("/ip4/" + str + "/tcp/" + port);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传绝对路径的文件
     */
    public String upLoadFile(String localFilePath) {
        NamedStreamable.FileWrapper fileAdd = new NamedStreamable.FileWrapper(new File(localFilePath));
        MerkleNode merkleNode = null;
        try {
            merkleNode = ipfs.add(fileAdd).get(0);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return merkleNode.toString();
    }

    /**
     * 上传字节流
     */
    public String upBytes(byte[] bytes) {
        NamedStreamable.ByteArrayWrapper byteArrayWrapper = new NamedStreamable.ByteArrayWrapper(bytes);
        MerkleNode merkleNode = null;
        try {
            merkleNode = ipfs.add(byteArrayWrapper).get(0);
            //  将 单一文件发布为 ipns 以保持不变
//            ipfs.name.publish(merkleNode.hash);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return merkleNode.hash.toString();
    }

    /**
     * 上传文件夹
     */
    public JSONObject upFolder() {
        NamedStreamable.FileWrapper fileAdd = new NamedStreamable.FileWrapper(new File("E:\\SuperMapData\\test1.txt"));
        List<NamedStreamable> children = new LinkedList<>();
        children.add(fileAdd);

        NamedStreamable.DirWrapper dirWrapper = new NamedStreamable.DirWrapper("test", children);
        MerkleNode merkleNode = null;
        try {
            // 这里需要获取文件的  merkleNode 才行，一般为最后一个
            List<MerkleNode> merkleNodes = ipfs.add(dirWrapper);
            merkleNode = merkleNodes.get(merkleNodes.size() - 1);
            //  将 单一文件发布为 ipns 以保持不变
            ipfs.name.publish(merkleNode.hash);
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject jsonObject = JSONObject.parseObject(merkleNode.toJSONString());
        return jsonObject;
    }

    /**
     * 下载文件 并保存到本地
     * @param hashID     需下载文件的 hash
     */
    public byte[] downloadBytes(String hashID){
        Multihash multihash = Multihash.fromBase58(hashID);
        byte[] fileContents = null;
        try {
            fileContents = ipfs.cat(multihash);
            ipfs.pin.add(multihash);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            logger.info( hashID + "is not exist");
        }
        return fileContents;

    }

    /**
     * 判断当前 hash 值在当前节点是否已经存储
     * @param hashID
     * @return
     */
    public boolean isExist(String hashID){
        Multihash multihash = Multihash.fromBase58(hashID);
        boolean exist = false;
        try {
            IPFS.Pin pin = ipfs.pin;
            List<Multihash> list = pin.rm(multihash);
            if (list.size() > 0){
                pin.add(multihash);
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            logger.info( hashID + " is not exist");
        }
        return exist;
    }

    public IPFS getIpfs(){
        return ipfs;
    }

}
